using System;

namespace ShadeTree.Binding
{
    public static class CoercionUtility
    {
        public static object Coerce(Accessor property, object rawValue)
        {
            Type propertyType = GetUnderlyingType(property);

            return Coerce(propertyType, rawValue);
        }

        public static object Coerce(Type propertyType, object rawValue)
        {
            if (rawValue == null || rawValue.Equals(string.Empty))
            {
                return null;
            }

            if (propertyType.IsEnum)
            {
                return Enum.Parse(propertyType, rawValue.ToString());
            }

            return Convert.ChangeType(rawValue, propertyType);
        }

        public static Type GetUnderlyingType(Accessor property)
        {
            Type propertyType = property.PropertyType;
            if (propertyType.IsGenericType && propertyType.GetGenericTypeDefinition().Equals(typeof (Nullable<>)))
            {
                propertyType = propertyType.GetGenericArguments()[0];
            }
            return propertyType;
        }

        public static int? CoerceToPositiveInteger(string textValue)
        {
            if (string.IsNullOrEmpty(textValue))
            {
                return null;
            }

            int returnValue = 0;
            if (int.TryParse(textValue, out returnValue))
            {
                if (returnValue >= 0)
                {
                    return returnValue;
                }
            }

            return null;
        }

        public static bool IsNumeric(Type type)
        {
            var numericTypes = new[] {typeof (double), typeof (long), typeof (int), typeof(decimal)};
            return Array.IndexOf(numericTypes, type) > -1;
        }
    }
}